#define _GNU_SOURCE
#define _FILE_OFFSET_BITS 64
#include <sys/types.h>
#include <dirent.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#if 0
struct dirent *readdir(DIR* DIRP);
struct dirent64 *readdir64(DIR* DIRP);

// Linux下读写超过2GB大文件需开启以下定义
方法1
在所有头文件之前添加，

#define _GNU_SOURCE
#define _FILE_OFFSET_BITS 64

或者更改编译选项

gcc -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64

方法2
定义_GNU_SOURCE，open的时候加上O_LARGEFILE参数，并且用lseek64代替lseek


struct dirent
  {
#ifndef __USE_FILE_OFFSET64
    __ino_t d_ino;
    __off_t d_off;
#else
    __ino64_t d_ino;
    __off64_t d_off;
#endif
    unsigned short int d_reclen;
    unsigned char d_type;
    char d_name[256];           /* We must not include limits.h! */
  };

#ifdef __USE_LARGEFILE64
struct dirent64
  {
    __ino64_t d_ino;
    __off64_t d_off;
    unsigned short int d_reclen;
    unsigned char d_type;
    char d_name[256];           /* We must not include limits.h! */
  };
#endif

readdir64() 函数类似于 readdir() 函数，是大型文件扩展名。

返回点 (.) 和点点 (..) 的条目 除文件系统根目录(例如 /c=/)之外的目录，在普通 Windows 路经。

readdir() 返回的指针指向可以被同一上对 readdir()的另一个调用覆盖目录流。但是，另一个调用 readdir()在 不同的目录流不会覆盖数据。

如果在最近一次调用 opendir() 或 rewinddir() 后从目录中删除文件，则后续调用readdir() 返回该文件的条目。 
如果在最近一次调用 opendir() 或 rewinddir() 之后将文件添加到目录中，则后续 调用readdir()不会返回添加的条目文件。

readdir() 填充 dirent 结构的所有成员，除了 d_ino 总是设置为 0。
readdir() 函数返回指向 键入包含成员d_name的结构 dirent。d_name数组的大小不是 指定;但是，终止 null 之前的字节数字符不能超过 NAME_MAX。

调用 fork() 后，父级和子级都可以 独立地继续使用 readdir() 或 rewinddir() 或两者处理目录流。 
目录流在成功调用 exec() 后关闭，因此子进程无法使用 在父进程中打开的目录流。

返回值
	如果成功，readdir() 和 readdir64() 返回指向对象的指针结构型 dirent 或结构型 dirent64。
	此结构被复制到静态中 特定于正在读取的目录流的内存。(随后 对同一目录流上的 readdir() 或 readdir64() 的调用会覆盖此内存区域。 
	当操作遇到 在目录的末尾，readdir() 返回一个 NULL 指针，并且不会更改 errno 来指示错误。 
	失败时，readdir() 和 readdir64() 返回一个 NULL 指针，并将 errno 设置为其中一个 以下值：

	EBADF 
		DIRP 不是指 打开目录流


移植问题
	文件和目录名称以多字节序列的形式返回，并从 Unicode (UTF-16) 转换 在从 Win32 返回之前。转换是根据 当前线程区域设置，
	使用 uselocale() 或进程区域设置设置 由调用 setlocale() 设置，并由 _NutConf() _NC_SET_ANSI_LOCALE和_NC_SET_UTF8_LOCALE选项覆盖。
	在所有其他下 条件中，多字节序列被视为来自当前 Windows 系统区域设置的 ANSI 代码页。

#endif

static int test() 
{
	DIR * p_dir = NULL;
	struct dirent64 * dp = NULL;
	int len = -1;
	char *name = "aaaaa";
	char *ptr;

	// 通过opendir打开目录
	p_dir = opendir("/proc");
	if (p_dir == NULL) {
	   return (-1);
	}

	len = strlen(name);

	//  开始遍历p_dir文件夹
	while ((dp = readdir64(p_dir)) != NULL) {	 
		//printf("inode number:%ld offset:%ld len:%d\n", dp->d_ino, dp->d_off, dp->d_reclen);
		printf("name:%s:%d\n", dp->d_name, dp->d_type);

		//  比较dp->d_name与name的值, 如果匹配则返回
		if (dp->d_reclen == len && strcmp(dp->d_name, name) == 0) {
			(void)closedir(p_dir);
			return 0;
		}

		if (strtol(dp->d_name, &ptr, 0xa) != 0)
			break;
	}

	printf("sizeof(struct dirent)=%d, -name=%d\n", sizeof(struct dirent64), sizeof(struct dirent64) - 256);
	printf("sizeof(ino_t)=%d, sizeof(off_t)=%d\n", sizeof(ino_t), sizeof(off_t));

	//  关闭dir
	(void)closedir(p_dir);

	return 0;
}

int main()
{
	test();

	return 0;
}


